package site.xuqing.appbus;

import site.xuqing.appbus.utils.RouteUtil;

/**
 * @author xuqing
 * @Description AppBus入口类
 * @createTime 2022年01月26日 16:04:05
 */
public class AppBus {
    private Server mServer;
    
    /**
     * 静态对象持有，不调用不实例化
     */
    private static class AppBusHolder {
        private static final AppBus INSTANCE = new AppBus();
    }
    
    private AppBus() {}
    
    public static AppBus getInstance() {
        return AppBusHolder.INSTANCE;
    }
    
    /**
     * 该方法需要在程序的入口方法中调用
     */
    public void init() {
        mServer = new Server();
    }
    
    /**
     * 注册当前对象，注册后才可接收到消息
     *
     * @param clazz 注册对象为Class<?>中
     * @return Client连接器，可使用client发送消息
     */
    public Client register(Class<?> clazz) {
        return register(RouteUtil.getRoute(clazz));
    }
    
    /**
     * 注册当前对象，注册后才可接收到消息
     *
     * @param object Object中注册
     * @return Client连接器，可使用client发送消息
     */
    public Client register(Object object) {
        return register(RouteUtil.getRoute(object));
    }
    
    /**
     * 注册当前对象，注册后才可接收到消息
     *
     * @param route String中注册
     * @return Client连接器，可使用client发送消息
     */
    public Client register(String route) {
        Client client = new Client(route, mServer);
        mServer.addClient(route, client);
        return client;
    }
    
    /**
     * 不注册，仅发送消息
     *
     * @param clazz 发送消息到Class<?>
     * @param data  需要发送的消息对象
     * @param <T>   消息的类型
     */
    public <T> void justSend(T data, Class<?> clazz) {
        justSend(data, RouteUtil.getRoute(clazz));
    }
    
    /**
     * 不注册，仅发送消息
     *
     * @param object 发送消息到Object
     * @param data   需要发送的消息对象
     * @param <T>    消息的类型
     */
    public <T> void justSend(T data, Object object) {
        justSend(data, RouteUtil.getRoute(object));
    }
    
    /**
     * 不注册，仅发送消息
     *
     * @param targetRoute 发送消息到注册到targetRoute的对象
     * @param data        需要发送的消息对象
     * @param <T>         消息的类型
     */
    public <T> void justSend(T data, String targetRoute) {
        Client client = new Client(null, mServer);
        client.send(data, targetRoute);
    }
    
    /**
     * 不注册，仅发送消息，多对象发送
     *
     * @param data    需要发送的消息
     * @param objects 需要发送的目标对象
     * @param <T>     消息的类型
     */
    public <T> void justSend(T data, Object... objects) {
        for (Object object : objects) {
            if (object instanceof String) {
                justSend(data, (String) object);
            } else if (object instanceof Class) {
                justSend(data, (Class<?>) object);
            } else {
                justSend(data, object);
            }
        }
    }
    
    /**
     * 注册，仅发送消息，所有象发送
     *
     * @param data 需要发送的目标对象
     * @param <T>  消息的类型
     */
    public <T> void justSendAll(T data) {
        Client client = new Client(null, mServer);
        client.sendAll(data);
    }
    
    /**
     * 取消注册
     *
     * @param clazz 在Class<?>中
     */
    public void unRegister(Class<?> clazz) {
        unRegister(RouteUtil.getRoute(clazz));
    }
    
    /**
     * 取消注册
     *
     * @param object 在Object中
     */
    public void unRegister(Object object) {
        unRegister(RouteUtil.getRoute(object));
    }
    
    /**
     * 取消注册
     *
     * @param targetRoute 注册targetRoute的对象中
     */
    public void unRegister(String targetRoute) {
        mServer.removeClient(targetRoute);
    }
    
    /**
     * 取消所有的注册
     */
    public void unRegisterAll() {
        mServer.removeAllClient();
    }
}
